// JavaScript Document
//用于记录图标数据的变量
var data = [];

//该平台使用echarts架构将从后台收集的数据显示为动态图表。
//图表的基本数据结构，echarts架构的数据结构
//https://echarts.apache.org/zh/option.html#title
//详细信息可以参考echarts的document
var optionDefault = {
    //标题的内容及格式
    title: {
        text: '采集结果',
        textStyle: {
            fontSize: 40,
            color: '#FFFFFF'
        },
		x:"center",
        //left: '40%',
        top: 8
    },
    tooltip: {
        trigger: 'axis',
        formatter: function (params) {
            params = params[0];
            return params.value[0] + ' : ' + params.value[1];
        },
        axisPointer: {
            animation: false
        }
    },
    grid: {
        show: true,
    },
    //x轴和y轴，由于两个工作模式坐标轴的设置区别很大，大部分内容在后边的handleResponse里。
    "animationDurationUpdate": 100,
    "series": []

};
var option = optionDefault;
////////////////////////////////////Socket/////////////////////////////////////////////////
//在id为message的对话框中追加显示str的内容。相当于控制一个状态显示器。
function textScreen(str) {
    jQuery("#message").append(str + '<br>');
    document.getElementById('message').scrollTop = document.getElementById('message').scrollHeight;
}


///////////////////////////////////////////vue/////////////////////////////////
//该平台使用Vue架构实现界面的动态交互，以及处理发送到后台与从后台接收的信息。

//弹窗组建的封装，减少html页面的冗余。
const popWindow = {
    data() {
        return {
            inputContent: ''
        }
    },
    props: ['type', 'show', 'title'],
    emits: ['confirmed', 'cancelled'],
    template: `
    <span v-if="type == 'alert'">
        <div class="popchart" v-cloak v-if="show">
            <div class="container" style="width: 300px">
                <div class="card popcard">
                    <div class="card-header bg-dark"> {{show}} </div>
                    <div class="card-body text-center bg-secondary">
                        <button class="btn btn-primary xbtn" @click="$emit('confirmed')">确定</button>
                    </div>
                </div>
            </div>
        </div>
    </span>
    <span v-if="type == 'input'">
        <div class="popchart" v-cloak v-if="show">
            <div class="container"  style="width: 500px">
                <div class="card popcard">
                    <div class="card-header bg-dark" >{{title}}</div>
                    <div class="card-body bg-secondary" >
                        <input v-model="inputContent" class="" style="width: 100%"/>
                    </div>
                    <div class="card-footer text-end bg-dark" >
                        <button class="btn btn-primary xbtn" @click="$emit('confirmed',inputContent)">确定</button>
                        &nbsp;
                        <button class="btn btn-danger xbtn" @click="$emit('cancelled')">取消</button>
                    </div>
                </div>
            </div>
        </div>
    </span>
    <span v-if="type == 'confirm'">
        <div class="popchart" v-cloak v-if="show">
            <div class="container" style="width: 500px">
                <div class="card popcard">
                    <div class="card-header bg-dark"> {{title}}? </div>
                    <div class="card-body text-end bg-secondary">
                        <button class="btn btn-primary xbtn" @click="$emit('confirmed')">确定</button>
                        &nbsp;
                        <button class="btn btn-danger xbtn" @click="$emit('cancelled')">取消</button>
                    </div>
                </div>
            </div>
        </div>
    </span>
    `
}

//vue的核心内容
const Interface = Vue.createApp({
    //name索引可以用于递归，这个架构中没有用到。
    name: 'Interface',
    //核心数据
    data() {
        return {
            //选择显示的面板索引
            boardShow: 0,
            //面板1（主面板）里的变量
            board1: {

                isPaused: false, //通过是否暂停来控制“暂停/继续”按钮的显示状态，false状态下显示“暂停”，true状态下显示“继续”
                isCharging: true, //显示充电状态
                btrPercent: '20%', //控制电量
                showMode: 1, //默认显示的模式
                process: '准备阶段', //显示充电状态
                prcPercent: '0%', //控制电量
                alertMessage: '', //弹出面板
                sampleConfirm: false,
            },
            //面板2（设置参数面板）里的变量
            board2: {
                //所有可以被用户编辑的参数
                paras: {
                    "idvt": {
                        'name': '电流时间',
                        'para': {
                            'AGND': '2.5', //# given by the particular LDO 
                            'drainV': '1.5E-3', //# ref AGND
                            'gateV': '1.205', //#ref AGND
                            'stepT': '0.1', //# step volt of sweeping
                            'settleT': '0.05', //# time before sample
                            'x_width': '30' // 横坐标宽度为30秒
                        }
                    },
                    "trans": {
                        'name': '转移曲线',
                        'para': {
                            'AGND': '2.5', //# given by the particular LDO 
                            'drainV': '0.5', //# ref AGND
                            'gateV_begin': '-0.8', //# ref AGND 
                            'gateV_end': '2', //# ref AGND
                            'stepV': '0.01', //# step volt of sweeping
                            'stepT': '0.05', //# hold time for each step
                            'settleT': '0.05' //# time before sample
                        }
                    },

                },
                paraLength: 0,
                //面板2中当前选中的项目
                select: 'idvt.AGND',
                //面板2中展示的设置项
                boardShow: 'idvt',
                //输入键盘的内容
                allkey: [
                    ['7', '8', '9', '←'],
                    ['4', '5', '6', '-'],
                    ['1', '2', '3', 'E'],
                    ['00', '0', '.', 'c']
                ],
            },
            board3: {
                Alg:"相对响应",
                background:0.0,
                threshold:0.0,
                factor:0.3,
                mode:"single",
                channels:["1"],
                switch:"off"
            },
            alias:{
                model:["背景电流(uA)","电流阈值(uA)","相对响应系数"]

            }
        }
    },
    methods: {
        //发送消息
        send(command, msg = '') {
            var dict = {
                "command": command,
                "msg": msg
            };
            cli.send(JSON.stringify(dict));
        },
        preMode() {
            var lastIndex = this.board2.paraLength - 1;
            this.board1.showMode -= 1;
            if (this.board1.showMode < 0) this.board1.showMode = lastIndex;
        },
        nextMode() {
            var lastIndex = this.board2.paraLength - 1;
            this.board1.showMode += 1;
            if (this.board1.showMode > lastIndex) this.board1.showMode = 0;
        },
        //后台开始收集的命令 #collect为转移曲线，#idvt为电流时间
        collect(type) {
            this.send('#stop');
            jQuery("#message").html("");
            data = [];
            textScreen("数据采集开始...")
            this.send(type);
        },
        //数字输入的软键盘控制器
        numType(key) {
            var select = this.board2.select.split('.');
            switch (key) {
                case 'c':
                    this.board2.paras[select[0]].para[select[1]] = '';
                    break;
                case '←':
                    var str = this.board2.paras[select[0]].para[select[1]];
                    if (str.length) {
                        this.board2.paras[select[0]].para[select[1]] = str.substring(0, str.length - 1);
                    }
                    break;
                default:
                    this.board2.paras[select[0]].para[select[1]] += key;
            }
        },
        //将字符串para里的参数提取并显示
        setP(para) {
            for (let key in this.board2.paras) {
                this.board2.paras[key] = null;
            }
            this.board2.paras = para;
            this.board2.paraLength = 0;
            for (let key in para) {
                this.board2.paraLength += 1;
                key;
            }
            for (let key in para) {
                this.board2.boardShow = key;
                for (let item in para[key]['para']) {
                    this.board2.select = key + '.' + item;
                    break;
                }
                break;
            }
        },
        //将修改后的参数发送到后台并保存
        savePara() {
            this.send('#set', JSON.stringify(this.board2.paras));
            this.boardShow = 0;
        },
        //获取默认参数
        getDefault() {
            this.send('#default');
        },
        setPB(proc, percent) {
            this.board1.process = proc;
            this.board1.prcPercent = percent;
        },
        getPT() {
            return [this.board2.paras.set.para['稳定时间'], this.board2.paras.set.para['采样时间']];
        },
        stop() {
            this.send('#stop', jQuery("#message").html().replaceAll('<br>', '\n'));
            clearInterval(time1);
            clearInterval(time2);
            setProgressBar("准备阶段", "0%")
        },
        sample() {
			sendMessage('timer',{name:"样品分析中",total:getProgressTime()[1],endcommand:"addmore"})
        },
        setA(msg) {
            this.board1.alertMessage = msg;
        },
        setSC(msg) {
            this.board1.sampleConfirm = msg;
        },
        savedata() {
            this.send('#save', jQuery("#message").html().replaceAll('<br>', '\n'));
        },
        modelSwitch(){
            if(this.board3.switch == 'on') this.board3.switch = 'off';
            else this.board3.switch = 'on';
            this.send('#model',JSON.stringify(this.board3));
        },
        modelSave(){
            this.send('#model',JSON.stringify(this.board3));
        },
        setIModel(model){
            this.board3 = model;
        },
        checkChannel(index){
            return this.board3.channels.indexOf(index)!=-1;
        },
        setChannelSingle(index){
            this.board3.channels = [index]
        },
        changeChannelMulti(index){
            if(this.board3.channels.indexOf(index)!=-1){
                this.board3.channels.splice(this.board3.channels.indexOf(index),1);
            } else {
                this.board3.channels.push(index);
            }
        },
        calS(a,b){
            console.log(parseFloat(a) + parseFloat(b));
            return parseFloat(a) + parseFloat(b);
        }
    },
    components: {
        popWindow
    },
    mounted() {
        //为vue框架内的方法提供外部接口
        window.setPara = this.setP;
        window.setProgressBar = this.setPB;
        window.getProgressTime = this.getPT;
        window.setAlert = this.setA;
        window.setSampleConfirm = this.setSC;
        window.sendMessage = this.send;
        window.setmodel = this.setIModel;
    }
});

//////////////////////////////////////////////////////////////////////////////////
//**********************全局变量系列******************************//
var chart1;
var tare = 0;
var setPara;
var setProgressBar;
var getProgressTime;
var setAlert;
var setSampleConfirm;
var sendMessage;
var time1;
var time2;
var average = 0.0;
var setmodel;
var cli;
//////////////////////////////////////////////////////////////////////////////////
jQuery(document).ready(() => {
	//连接websockets服务器，这里使用window.location.hostname是因为不确定主机的实际ip，这个是动态的。
    cli = new WebSocket('ws://' + window.location.hostname + ':9575/');

    //连接成功之后的响应
    cli.onopen = function () {
        textScreen("星尘采集系统连接成功...")
    };
    //装在vue和echarts框架
    Interface.mount('#maincontrol');
    chart1 = echarts.init(document.getElementById('main'));
    chart1.setOption(option);
    var xcounts = 0;
    //处理后台返回信息的函数

    function handleResponse(resp) {
        resp = JSON.parse(resp);
		window.console.log(resp);
        var xy;
        if (resp.type === "text") {
            textScreen(resp.value);
        } else if (resp.type === "data") {
            //textScreen(resp.value)
            xy = eval(resp.value);
            op = chart1.getOption();
            //op.xAxis.data.push(xy[0]);
            //xy 0:x-axis,1:series0,2:series1
            for (let i = 0; i < Math.min(op.series.length, xy.length - 1); i++) {
                op.series[i].data.push([xy[0], xy[i + 1]]);
                if (xcounts != 0 && op.series[i].data.length > xcounts) {
                    op.series[i].data.shift();
                }
            }
            console.log(op)
            var sum = 0;
            for (let i = 0; i < op.series[0].data.length; i++) {
                sum += op.series[0].data[i][1];
            }
            average = sum / op.series[0].data.length;

            chart1.setOption(op);

        } else if (resp.type === "para") {
            setPara(resp.value);
        } else if (resp.type === "echarts") {
			chart1.setOption(optionDefault,true);
            chart1.setOption(JSON.parse(resp.value));
        } else if (resp.type === "xcounts") {
            xcounts = resp.value;
        } else if (resp.type === "clean") {
            jQuery("#message").html("");
            textScreen(resp.value);
        } else if (resp.type === "tare") {
            textScreen('I0: ' + resp.value);
			tare = eval(resp.value);
        }else if (resp.type === "trans") {
            setProgressBar("转移曲线采集", resp.value)
        }else if (resp.type === "model") {
            setmodel(resp.value);
        }else if (resp.type === "start") {
            var stableTime = getProgressTime()[0] * 1000;
            textScreen("系统稳定中，请稍后...")
			sendMessage('timer',{name:"系统稳定中",total:getProgressTime()[0],endcommand:"addliquid"})
        }else if (resp.type === "alert"){
            setAlert(resp.value)
        }else if (resp.type === "bar"){
			setAlert("");
			setSampleConfirm(false);
            setProgressBar(resp.value.name,resp.value.value)
        }else if (resp.type === "addliquid"){
			setAlert("请滴加样品");
        }else if (resp.type === "addmore"){
			sendMessage('#tare');
			setSampleConfirm(true);
            if(tare == 0) textScreen('Average: ' + average +'|I0=0!');
            else textScreen('Average: ' + (average-tare)/tare);
            
        }
    }
    cli.onmessage = function (msg) {
        handleResponse(msg.data);
    };
});

//清除所有数据和对话框的内容
function clearScreen() {
    data = [];
    chart1.setOption({
        xAxis: {
            name: ''
        },
        yAxis: {
            name: ''
        },
        series: [{
            data: data
        }]
    });
    jQuery("#message").html("");
}

//用于切换是否全屏的函数，isfull用来记录当前状态，
//false为非全屏，true为全屏
var isfull = false;

function full() {
    if (isfull === false) {
        var de = document.documentElement;
        if (de.requestFullscreen) {
            de.requestFullscreen();
        } else if (de.mozRequestFullScreen) {
            de.mozRequestFullScreen();
        } else if (de.webkitRequestFullScreen) {
            de.webkitRequestFullScreen();
        }
        //适配不同的浏览器
        isfull = true;
    } else {
        de = document;
        if (de.exitFullscreen) {
            de.exitFullscreen();
        } else if (de.mozCancelFullScreen) {
            de.mozCancelFullScreen();
        } else if (de.webkitCancelFullScreen) {
            de.webkitCancelFullScreen();
        }
        //适配不同的浏览器
        isfull = false;
    }
}

//刷新页面
function fresh() {
    location.replace(window.location.href);
    full();
}
